home *** CD-ROM | disk | FTP | other *** search
- /*
- name: amiga.c
-
- Amiga display routines
- ----------------------
-
- Currently supported displaymodes:
-
- 0 - No display (default)
- 1 - HAM6, lowres, non-interlaced
- 2 - Grayscale (16 colors), hires, interlaced
-
- */
-
-
- #include <stdio.h>
- #include <dos.h>
- #include <intuition/intuition.h>
- #include <exec/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
-
- #include "defs.h"
- #include "extern.h"
-
-
- /* Prototypes for some subroutines */
-
- void OpenAmigaScreen(struct NewScreen *ScreenPars,struct NewWindow *WindowPars, UWORD Palette[], ULONG NumCols);
- void CloseAmigaScreen(void);
- UBYTE ConvertColorToHam6(unsigned char RGBColor[], int x, int y);
- UBYTE ConvertColorToGray(unsigned char RGBColor[], int x, int y);
- UBYTE MG_Dither8(UBYTE Value, int x, int y);
- void MG_Dither24(UBYTE RGBColor12[],unsigned char RGBColor24[], int x, int y);
- int BreakHandler(void);
-
-
- /* Some declarations */
-
- #define SCREEN_TITLE_HEIGHT 11
-
- #define DISPLAY_NONE 0 /* Different display modes */
- #define DISPLAY_HAM6 1
- #define DISPLAY_GRAY 2
-
- #define HAM_MODE_PAL 0x00
- #define HAM_MODE_RED 0x20
- #define HAM_MODE_GRN 0x30
- #define HAM_MODE_BLU 0x10
-
-
- /* Some global variables */
-
- int CurrentDisplayType;
- UBYTE Last12BitColor[3] = {0,0,0};
-
- struct Screen *RL_Screen = NULL;
- struct Window *RL_Window = NULL;
- struct RastPort *RL_RastPort = NULL;
- struct ViewPort *RL_ViewPort = NULL;
- struct IntuitionBase *IntBase = NULL;
- struct GfxBase *GfxBase = NULL;
-
-
- UWORD Ham6Palette[16] = {
- 0x000, 0xAAA, 0x555, 0xFFF,
- 0x808, 0xF4A, 0xE00, 0x620,
- 0xF60, 0xFA8, 0xFE0, 0x080,
- 0x0D0, 0x0CC, 0x06F, 0x00A
- };
-
- UWORD GrayPalette[16] = {
- 0x000, 0x111, 0x222, 0x333,
- 0x444, 0x555, 0x666, 0x777,
- 0x888, 0x999, 0xAAA, 0xBBB,
- 0xCCC, 0xDDD, 0xEEE, 0xFFF
- };
-
-
- UWORD DitherMask[16] = {
- 0x8000, 0x8080, 0x8410, 0x8888,
- 0x9224, 0xA492, 0xA94A, 0xAAAA,
- 0xD555, 0xD6B5, 0xDB6D, 0xEDDB,
- 0xF777, 0xFBEF, 0xFF7F, 0xFFFF
- };
-
- UBYTE DitherYTable[16] = {
- 0x08, 0x0B, 0x0E, 0x0F, 0x10, 0x0F, 0x0E, 0x0B,
- 0x08, 0x05, 0x02, 0x01, 0x00, 0x01, 0x02, 0x05
- };
-
- struct TextAttr TopazAttr =
- {(STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0};
-
-
- /******************************************************************
- *
- * OpenDisplay()
- *
- ******************************************************************/
-
- long OpenDisplay(long DisplayType)
- {
- long Ret_OK;
-
- struct NewScreen ScreenPars =
- {
- 0, 0, /* LeftEdge, TopEdge */
- NULL, NULL, /* Set screen size later */
- NULL, /* Set depth later */
- 2, 7, /* DetailPen, BlockPen */
- NULL, /* Set display-mode later */
- CUSTOMSCREEN, /* SCREENQUIET ? */
- NULL, /* Set font later */
- "RayLab 1.0 display", /* Title */
- NULL, /* No special gadgets */
- NULL /* Nu custom bitmap */
- };
-
- struct NewWindow WindowPars =
- {
- 0, SCREEN_TITLE_HEIGHT, /* LeftEdge, TopEdge*/
- NULL, NULL, /* Set screen size later */
- 3, 7, /* DetailPen, BlockPen */
- MENUPICK, /* IDCMP */
- SMART_REFRESH | BORDERLESS | NOCAREREFRESH | ACTIVATE,
- NULL, /* No special gadgets */
- NULL, /* No checkmark */
- NULL, /* No window title */
- NULL, /* Set screen later */
- NULL, /* No bitmap */
- NULL, NULL, /* Set min size later */
- NULL, NULL, /* Set max size later */
- CUSTOMSCREEN
- };
-
-
- RL_Screen = NULL; RL_Window = NULL;
-
- (void) onbreak((int (*)(void))BreakHandler); /* Install break-handler */
-
- IntBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library",33);
-
- if(IntBase==NULL) {
- fprintf(stderr,"Error: Could not open intuition.library; no display possible\n\n");
- IntBase = NULL;
- }
- else {
- GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library",33);
- if(GfxBase==NULL) {
- fprintf(stderr,"Error: Could not open graphics.library; no display possible\n\n");
- CloseLibrary((struct Library *)IntBase);
- IntBase = NULL; GfxBase = NULL;
- }
- }
-
- if( (IntBase!=NULL) && (GfxBase!=NULL) ) {
- if( (DisplayType>DISPLAY_NONE) && (DisplayType<=DISPLAY_GRAY) ) {
- CurrentDisplayType = DisplayType;
-
- ScreenPars.Width = (SHORT)PicWidth;
- ScreenPars.Height = (SHORT)(PicHeight+SCREEN_TITLE_HEIGHT);
- ScreenPars.Font = &TopazAttr;
-
- WindowPars.Width = (SHORT)PicWidth;
- WindowPars.Height = (SHORT)PicHeight;
- WindowPars.MinWidth = WindowPars.MaxWidth = (SHORT)PicWidth;
- WindowPars.MinHeight = WindowPars.MaxHeight = (SHORT)PicHeight;
-
- switch(CurrentDisplayType) {
- case DISPLAY_HAM6:
- ScreenPars.ViewModes = HAM;
- ScreenPars.Depth = 6;
- OpenAmigaScreen(&ScreenPars,&WindowPars,Ham6Palette,16L);
- break;
-
- case DISPLAY_GRAY:
- ScreenPars.ViewModes = HIRES | LACE;
- ScreenPars.Depth = 4;
- OpenAmigaScreen(&ScreenPars,&WindowPars,GrayPalette,16L);
- break;
-
- case DISPLAY_NONE:
- break;
- }
- }
- else {
- if(DisplayType!=DISPLAY_NONE)
- fprintf(stderr,"Warning: Unsupported display type (%d), no display opened\n\n",DisplayType);
- CurrentDisplayType = DISPLAY_NONE;
- }
- }
- else {
- CurrentDisplayType = DISPLAY_NONE;
- }
-
- Ret_OK = 0L;
- if(CurrentDisplayType!=DISPLAY_NONE) {
- Ret_OK = 1L;
- }
-
- return(Ret_OK);
- }
-
-
- /******************************************************************
- *
- * CloseDisplay()
- *
- ******************************************************************/
-
- void CloseDisplay(void)
- {
- ULONG done, signalmask, signals, class, code, menunum, itemnum;
- struct IntuiMessage *message;
-
- if((CurrentDisplayType!=0)&&(picturerendering!=0)) {
- CloseAmigaScreen();
- }
- else if((CurrentDisplayType!=0)&&(picturerendering==0)) {
- struct IntuiText ItemsText[] =
- {
- {2,1,JAM1,2,1,NULL," Close", NULL}
- };
-
- struct MenuItem Items[] =
- {
- {
- NULL, /* No more items */
- 0, 1, 110, 10, /* Left, top, width, height */
- ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHBOX,
- 0, /* MutualExclude */
- NULL, /* Set item text later */
- NULL,
- 'C', /* Key equivalent */
- NULL, /* Sub item */
- MENUNULL /* NextSelect */
- }
- };
-
- struct Menu MenuPars =
- {
- NULL, /* No more menus */
- 0, 0, 120, 40, /* Left, top, width, height */
- MENUENABLED, /* Flags */
- "Action", /* Menu name */
- NULL /* Set first item later */
- };
-
- ItemsText[0].ITextFont = &TopazAttr;
- Items[0].ItemFill = &ItemsText[0];
- MenuPars.FirstItem = &Items[0];
-
- SetMenuStrip(RL_Window, &MenuPars); /* Add menu */
-
-
- signalmask = 1L << RL_Window->UserPort->mp_SigBit;
- done = 0L;
-
- while( done == 0L ) {
- signals = Wait(signalmask);
- if((signals&signalmask)!=0L) {
- while( message = (struct IntuiMessage *)GetMsg(RL_Window->UserPort) ) {
- class = message->Class;
- code = message->Code;
- ReplyMsg((struct Message *)message);
- if(class==MENUPICK) {
- menunum = MENUNUM(code);
- itemnum = ITEMNUM(code);
- if(menunum==0L) {
- if(itemnum==0L) {
- CloseAmigaScreen();
- done = 1L;
- }
- }
- }
- }
- }
- }
- }
- }
-
-
- /******************************************************************
- *
- * DisplayPlot()
- *
- ******************************************************************/
-
- void DisplayPlot(int x, int y, unsigned char RGBColor[])
- {
- switch(CurrentDisplayType) {
- case DISPLAY_NONE:
- break;
-
- case DISPLAY_HAM6:
- SetAPen(RL_RastPort, ConvertColorToHam6(RGBColor,x,y));
- (void) WritePixel(RL_RastPort,x,y);
- break;
-
- case DISPLAY_GRAY:
- SetAPen(RL_RastPort, ConvertColorToGray(RGBColor,x,y));
- (void) WritePixel(RL_RastPort,x,y);
- break;
- }
- }
-
-
- /******************************************************************
-
- This routine is called if CTRL-C is issued
-
- ******************************************************************/
-
- int BreakHandler(void)
- {
- fprintf(stderr,"\n*** The execution of RayLab was terminated by the user\n");
- cleanup();
- return(1); /* Exit RayLab after this */
- }
-
-
- /******************************************************************
-
- Some routines for converting 24-bit rgb colors to apropriate
- display-modes
-
- ******************************************************************/
-
-
- UBYTE ConvertColorToHam6(unsigned char RGBColor[], int x, int y) {
- UBYTE New12BitColor[3];
- UBYTE HamMode, HamCol;
- long Diff12BitColor[3];
- register long RGBDiff, t1, t2, t3, t4, i, BestColor;
-
- if(x==0) {
- t1 = Ham6Palette[0];
- Last12BitColor[0] = (t1&0xf00)>>8;
- Last12BitColor[1] = (t1&0x0f0)>>4;
- Last12BitColor[2] = t1&0x00f;
- }
-
- /* When dithering, it seems best to use the 24-bit color for comparsion: */
-
- Diff12BitColor[0] = (long)RGBColor[0]-(long)(Last12BitColor[0]<<4);
- Diff12BitColor[1] = (long)RGBColor[1]-(long)(Last12BitColor[1]<<4);
- Diff12BitColor[2] = (long)RGBColor[2]-(long)(Last12BitColor[2]<<4);
- Diff12BitColor[0] *= Diff12BitColor[0];
- Diff12BitColor[1] *= Diff12BitColor[1];
- Diff12BitColor[2] *= Diff12BitColor[2];
- HamMode = HAM_MODE_RED;
- if(Diff12BitColor[1]>Diff12BitColor[0]) {
- HamMode = HAM_MODE_GRN;
- if(Diff12BitColor[2]>Diff12BitColor[1]) {
- HamMode = HAM_MODE_BLU;
- }
- }
- else {
- if(Diff12BitColor[2]>Diff12BitColor[0]) {
- HamMode = HAM_MODE_BLU;
- }
- }
- Diff12BitColor[0] = Diff12BitColor[0]>>8;
- Diff12BitColor[1] = Diff12BitColor[1]>>8;
- Diff12BitColor[2] = Diff12BitColor[2]>>8;
-
- MG_Dither24(New12BitColor,RGBColor,x,y);
-
- switch(HamMode) {
- case HAM_MODE_RED:
- HamCol = Last12BitColor[0] = New12BitColor[0];
- RGBDiff = Diff12BitColor[1] + Diff12BitColor[2];
- break;
- case HAM_MODE_GRN:
- HamCol = Last12BitColor[1] = New12BitColor[1];
- RGBDiff = Diff12BitColor[0] + Diff12BitColor[2];
- break;
- case HAM_MODE_BLU:
- HamCol = Last12BitColor[2] = New12BitColor[2];
- RGBDiff = Diff12BitColor[0] + Diff12BitColor[1];
- break;
- }
-
- BestColor = 100;
- for(i=0;i<16;i++) {
- t1 = (long)Ham6Palette[i];
- t2 = ((t1&0xf00)>>8) - (long)New12BitColor[0]; t2 *= t2;
- t3 = ((t1&0x0f0)>>4) - (long)New12BitColor[1]; t3 *= t3;
- t4 = (t1&0x00f) - (long)New12BitColor[2]; t4 *= t4;
- t1 = t2+t3+t4;
- if(RGBDiff>t1) {
- RGBDiff = t1;
- BestColor = i;
- }
- }
- if(BestColor<16) {
- HamMode = HAM_MODE_PAL;
- HamCol = (UBYTE)BestColor;
- t1 = Ham6Palette[BestColor];
- Last12BitColor[0] = (t1&0xf00)>>8;
- Last12BitColor[1] = (t1&0x0f0)>>4;
- Last12BitColor[2] = t1&0x00f;
- }
-
- return((UBYTE)(HamMode | (HamCol&0x0f)));
- }
-
-
-
- UBYTE ConvertColorToGray(unsigned char RGBColor[], int x, int y)
- {
- UBYTE Gray;
-
- Gray = (UBYTE)(((UWORD)RGBColor[0]+(UWORD)RGBColor[1]+(UWORD)RGBColor[2])/(UWORD)3);
- return(MG_Dither8(Gray,x,y));
- }
-
-
-
- /* This is some strange dithering method that */
- /* I managed to produce late one night */
-
- UBYTE MG_Dither8(UBYTE Value, int x, int y)
- {
- UBYTE Dithered;
-
- Dithered = Value>>4;
- if(Dithered<15) {
- if(((0x01<<(((y<<2)+x+DitherYTable[y&0x000f])&0x000f))&DitherMask[Value&0x0f])!=0) Dithered++;
- }
- return(Dithered);
- }
-
-
- void MG_Dither24(UBYTE RGBColor12[], unsigned char RGBColor24[], int x, int y)
- {
- register int Dither;
-
- RGBColor12[0] = (RGBColor24[0]>>4)&0x0f;
- RGBColor12[1] = (RGBColor24[1]>>4)&0x0f;
- RGBColor12[2] = (RGBColor24[2]>>4)&0x0f;
- Dither = 0x01<<(((y<<2)+x+DitherYTable[y&0x000f])&0x000f);
- if((RGBColor12[0]<15)&(Dither&DitherMask[RGBColor24[0]&0x0f])!=0) RGBColor12[0]++;
- if((RGBColor12[1]<15)&(Dither&DitherMask[RGBColor24[1]&0x0f])!=0) RGBColor12[1]++;
- if((RGBColor12[2]<15)&(Dither&DitherMask[RGBColor24[2]&0x0f])!=0) RGBColor12[2]++;
- }
-
-
- /*
- A routine for simplifying the opening of Amiga screens and windows
- */
-
- void OpenAmigaScreen(struct NewScreen *ScreenPars,struct NewWindow *WindowPars, UWORD Palette[], ULONG NumCols)
- {
- RL_Screen = (struct Screen *)OpenScreen(ScreenPars);
- if(RL_Screen!=NULL) {
- WindowPars->Screen = RL_Screen;
- RL_Window = (struct Window *)OpenWindow(WindowPars);
- if(RL_Window!=NULL) {
- RL_RastPort = RL_Window->RPort;
- RL_ViewPort = &(RL_Screen->ViewPort);
- LoadRGB4(RL_ViewPort,Palette,NumCols);
- SetDrMd(RL_RastPort, JAM1);
- }
- else {
- RL_RastPort = NULL;
- fprintf(stderr,"Error: Could not open display window\n\n");
- CurrentDisplayType = DISPLAY_NONE;
- CloseScreen(RL_Screen);
- RL_Screen = NULL; RL_Window = NULL;
- }
- }
- else {
- fprintf(stderr,"Error: Could not open display screen\n\n");
- CurrentDisplayType = DISPLAY_NONE;
- RL_Screen = NULL; RL_Window = NULL;
- }
- }
-
-
- void CloseAmigaScreen(void)
- {
- CurrentDisplayType = DISPLAY_NONE;
- if(RL_Window!=NULL) {
- if(RL_Window->MenuStrip)
- ClearMenuStrip(RL_Window); /* Remove menu */
- CloseWindow(RL_Window); /* Close window */
- RL_Window = NULL;
- }
- if(RL_Screen!=NULL) {
- CloseScreen(RL_Screen); /* Close screen */
- RL_Screen = NULL;
- }
- if(GfxBase!=NULL) {
- CloseLibrary((struct Library *)GfxBase); /* Close graphics.library */
- GfxBase = NULL;
- }
- if(IntBase!=NULL) {
- CloseLibrary((struct Library *)IntBase); /* Close intuition.library */
- IntBase = NULL;
- }
- }
-